namespace MLSharp.Clustering
{
	/// <summary>
	/// Statistics for an attribute.  For continuous attributes,
	/// this is average and standard deviation.  For discrete attributes, this
	/// is a probability of an attribute taking a particular value.
	/// </summary>
	public class AttributeStatistic
	{
		#region Properties

		/// <summary>
		/// The minimum value observed for a numeric attribute.
		/// </summary>
		public double Minimum { get; private set; }

		/// <summary>
		/// The maximum value observed for a numeric attribute.
		/// </summary>
		public double Maximum { get; private set; }

		/// <summary>
		/// The name of the attribute.
		/// </summary>
		public string Name { get; private set; }

		/// <summary>
		/// The average attribute value (for numeric attributes only).
		/// </summary>
		public double Mean { get; private set; }

		/// <summary>
		/// The standard deviation (for numeric attributes only).
		/// </summary>
		public double StdDev { get; private set; }

		/// <summary>
		/// The value of the attribute (for set attributes only).
		/// </summary>
		public string AttributeValue { get; private set; }

		/// <summary>
		/// The probability of the attribute taking on the corresponding
		/// value (for set attributes only).
		/// </summary>
		public double Probability { get; private set; }

		#endregion

		#region Constructors

		/// <summary>
		/// Creates a statistic for a numeric attribute.
		/// </summary>
		/// <param name="name"></param>
		/// <param name="maximum"></param>
		/// <param name="mean"></param>
		/// <param name="minimum"></param>
		/// <param name="stdDev"></param>
		public AttributeStatistic(string name, double minimum, double mean, double maximum, double stdDev)
		{
			Name = name;
			Minimum = minimum;
			Mean = mean;
			Maximum = maximum;
			StdDev = stdDev;

			Probability = double.NaN;
		}

		/// <summary>
		/// Creates a statistic for a nominal attribute.
		/// </summary>
		/// <param name="name"></param>
		/// <param name="value"></param>
		/// <param name="probability"></param>
		public AttributeStatistic(string name, string value, double probability)
		{
			Name = name;
			AttributeValue = value;
			Probability = probability;

			Minimum = Mean = Maximum = StdDev = double.NaN;
		}

		#endregion

		#region Public Methods

		/// <summary>
		/// Returns a correctly formatted representation of the stat.
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			//If the mean is defined, it is a numeric attribute.
			if (!double.IsNaN(Mean))
			{
				return string.Format("{0}: {1} [{2}] ({3} - {4})", Name,
				                     Mean, StdDev, Minimum, Maximum);
			}
			else
			{
				return string.Format("P({0}={1}): {2}", Name, AttributeValue, Probability);
			}
		}

		#endregion
	}
}